﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Microsoft.SharePoint.Administration;
using SharepointSolutionInstaller.Views;
using SharepointSolutionInstaller.Resources;
using Microsoft.SharePoint;
using System.Data.SqlClient;
using SharepointSolutionInstaller.Utils.Configuration;
using SharepointSolutionInstaller.Utils.Log;

namespace SharepointSolutionInstaller.Utils.SolutionDeployment
{

    /// <summary>
    /// Command for creating a deployment job.
    /// </summary>
    public class CreateDeploymentJobCommand : JobCommand
    {
        private readonly Collection<SPWebApplication> applications;
        Guid solutionId;
        string solutionName;
        internal CreateDeploymentJobCommand(InstallProcess parent, IList<SPWebApplication> applications, Guid solutionId, string solutionName)
            : base(parent)
        {
            this.solutionId = solutionId;
            this.solutionName = solutionName;
            if (applications != null)
            {
                this.applications = new Collection<SPWebApplication>();
                foreach (SPWebApplication application in applications)
                {
                    this.applications.Add(application);
                }
            }
            else
            {
                this.applications = null;
            }
        }

        internal override string Description
        {
            get
            {
                return CommonUIStrings.createDeploymentJobCommand;
            }
        }

        protected internal override bool Execute()
        {
            try
            {
                SPSolution installedSolution = SPFarm.Local.Solutions[solutionId];

                //
                // Remove existing job, if any. 
                //
                if (installedSolution.JobExists)
                {
                    RemoveExistingJob(installedSolution);
                }

                log.Info("***** SOLUTION" + solutionName + " DEPLOYMENT *****");
                if (installedSolution.ContainsWebApplicationResource && applications != null && applications.Count > 0)
                {
                    installedSolution.Deploy(GetImmediateJobTime(), true, applications, true);
                }
                else
                {
                    installedSolution.Deploy(GetImmediateJobTime(), true, true);
                }

                return true;
            }

            catch (SPException ex)
            {
                throw new Exception(ex.Message, ex);
            }

            catch (SqlException ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        protected internal override bool Rollback()
        {
            SPSolution installedSolution = SPFarm.Local.Solutions[solutionId];

            if (installedSolution != null)
            {
                //
                // Remove existing job, if any. 
                //
                if (installedSolution.JobExists)
                {
                    RemoveExistingJob(installedSolution);
                }

                log.Info("***** SOLUTION RETRACTION *****");
                if (installedSolution.ContainsWebApplicationResource)
                {
                    installedSolution.Retract(GetImmediateJobTime(), applications);
                }
                else
                {
                    installedSolution.Retract(GetImmediateJobTime());
                }
            }
            return true;
        }
    }
}
